#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>

using std::cout;
using std::endl;

using std::rand;
using std::srand;

using std::time;

typedef struct no
{
    int value;
    no * next;
} NO;

void printPercentage( int type, int percent )
{
    if( type == 0 )
        fprintf(stderr, "\rmemory alloc ");
    else
        fprintf(stderr, "\rmemory free  ");

    // imprime os '#' onde 50x '#' = 100%
    int i = 0;
    while( i <= percent / 2.0)
    {
        fprintf(stderr, "#");
        i++;
    }
    int j = 0;
    while( j <= (100 / 2.0 ) - i )
    {
        fprintf(stderr, " ");
        j++;
    }
    fprintf(stderr, "%4d%%", percent);
}


int main()
{
    NO* initial;
    NO* curr;
    NO* newNo;

    //initial = (NO *)malloc(sizeof( NO ));
    initial = new NO;
    curr = initial;

    // seta a semente aleatoria
    srand( time( 0 ) );
    initial->value = 1 + rand() % 100;

    // Aloca espaco grande de memoria
     const int total = 15000000; // VALGRIND
    //const int total = 200000000; // APP

    // Imprime a quantidade de bytes
    fprintf(stderr, "DATA TO ALLOC:\n");
    fprintf(stderr, "sizeof( NO ) = %d Bytes\n", sizeof( NO ) );
    fprintf(stderr, "total nodes = %d\n", total );
    fprintf(stderr, "total memory = %d MBytes\n\n", (total / ( 1024 * 2024 ))* sizeof( NO ) );
    int frac, last = -1;
    long int i;
    // aumente os 30000000 aos poucos. proximo do limite para 8GB
    for( i = 0; i < total; i++ )
    {
        frac = ( i * 100 ) / total + 1;
        if( frac > last )
        {
            printPercentage( 0, frac );
            last = frac;
        }

        //newNo = (NO *)malloc( sizeof( NO ));
        newNo = new NO;
        newNo->value = 1 + rand() % 100;
        newNo->next = 0;
        curr->next = newNo;
        curr = newNo;
    }
    fprintf(stderr, "\n");

    // Limpando a memoria
    NO* p;
    p = initial->next;
    curr = initial;
    last = -1;
    i = 0;
    while( curr != 0 )
    {
        // Imprime a barra de porcentagem
        frac = ( i * 100 ) / total;
        if( frac > last )
        {
            printPercentage( 1, frac );
            last = frac;
        }

        // Desaloca a memoria do elemento corrente e realinha os ponteiros
        delete curr;
        curr = 0;
        curr = p;
        if( p != 0 )
            p = p->next;

        // Incrementa para calculo de porcentagem
        i++;
    }
    // Devolve o prompt em nova linha
    fprintf(stderr, "\n");

    return 0;
}


